package com.ficus.road.maintain.process;

import com.ficus.road.maintain.config.DiseaseConfig;
import com.ficus.road.maintain.core.model.Confirmation;
import com.ficus.road.maintain.core.model.FrameDTO;
import com.ficus.road.maintain.core.model.Hit;
import com.ficus.road.maintain.service.HitService;
import com.ficus.road.maintain.websocket.WebSocketManager;
import com.ficus.road.maintain.websocket.WebSocketReplayManager;
import lombok.extern.slf4j.Slf4j;

import java.util.List;
import java.util.Map;

@Slf4j
public class ReplayDataProcessor extends BaseProcessor {

    ReplayDrawerProcessor replayDrawerProcessor;

    DrawerProcessor drawerProcessor;
    boolean isLive;

    public boolean isWSAvaliable() {
        return replayDrawerProcessor.isWsAvailable();
    }

    public ReplayDataProcessor(WebSocketReplayManager webSocketReplayManager, WebSocketManager webSocketManager, DiseaseConfig diseaseConfig,
                               int maxDistance, boolean hitCheck, HitService hitService, boolean isLive, int delayTime, double rateLimiterThreshold) {
        super(diseaseConfig, maxDistance, hitCheck);
        this.isLive = isLive;
        if (isLive) {
            this.drawerProcessor = new DrawerProcessor("drawerProcessor", webSocketManager, hitService, delayTime);
            drawerProcessor.start();
        } else {
            this.replayDrawerProcessor = new ReplayDrawerProcessor("replayDrawerProcessor", webSocketReplayManager, hitService, rateLimiterThreshold);
            replayDrawerProcessor.start();
        }
    }

    @Override
    public boolean isWsConnect(String uuid) {
        return LoadSsfFileProcessor.playFlag.get().containsKey(uuid) || LoadSsfFileProcessor.liveCarSet.get().containsKey(uuid);
    }

    @Override
    public int getMaxQueueSize() {
        return 100;
    }

    /**
     * 让replayDataProcessor和replayDrawerProcessor退出while循环
     * 调用时机不对, readMetaFile方法很快跑完, 前端可能还没调用stop方法
     */
    public void stop() {
        run.set(false);
        replayDrawerProcessor.stopThread();
    }

    @Override
    public Confirmation.ConfirmationStatus getHitStatus() {
        return Confirmation.ConfirmationStatus.TO_BE_CONFIRMED;
    }

    @Override
    public void saveHitInfo(FrameDTO value, List<Hit> hits) {
        value.setHits(hits);
    }

    @Override
    public void sendDrawer(FrameDTO value) {
        if (isLive) {
            drawerProcessor.put(value);
        } else {
            replayDrawerProcessor.put(value);
        }
    }

    public void closeWs(String uuid) {
        replayDrawerProcessor.closeWs(uuid);
    }

    public void putReplayHits(Map<Long, List<Hit>> hitsMap, long time) {
        replayDrawerProcessor.putReplayHits(hitsMap, time);
    }
}
